/*
 * @Description: 
 * @Version: 1.0
 * @Autor: c-jack.qian
 * @Date: 2021-04-16 11:37:49
 * @LastEditors: c-jack.qian
 * @LastEditTime: 2021-04-16 14:53:41
 */
let Vue = null
export default class VueRouter {
    // 判断是否已注册过这个插件
    // 把构造函数vue记录到全局
    // 创建vue实例的时候拔router对象注入到vue实例中
    // 创建router-link router-view 组件
    // 添加监听hash路径变化事件 hashchange 
    static install(_Vue) {
        if (this.install.installed) {
            return;
        }
        this.install.installed = true

        Vue = _Vue

        Vue.mixin({
            beforeCreate() {
                if (this.$options.router) {
                    _Vue.prototype.$router = this.$options.router
                    this.$options.router.init()
                }
            }
        })
    }

    // 初始化options
    // 初始化响应式对象data
    // 初始化存放路由地址和组件作为键值对的对象routerMap
    constructor(options) {
        this.options = options
        // 获取当前地址栏上的hash路径
        const currentUrl = window.location.hash
        this.data = Vue.observable({
            current: currentUrl
        })
        this.routerMap = {}
    }

    // 初始化三个方法
    init() {
        this.createRouterMap()
        this.createComponent()
        this.addUrlHashChangeListener()
    }

    // 创建路由路径和组件映射的对象
    createRouterMap() {
        this.options.routes.forEach((item) => {
            this.routerMap[`#${item.path}`] = item.component
        })
    }

    // 创建router-link router-view组件
    createComponent() {
        const vueRouterThis = this
        Vue.component('router-link', {
            props: {
                to: String,
            },
            render(h) {
                // 创建一个虚拟dom 并返回，下面代码的this是一个vue实例
                return h('a', {
                    attrs: {
                        href: `#${this.to}`
                    },
                }, this.$slots.default)
            },
        })

        Vue.component('router-view', {
            render(h) {
                const url = vueRouterThis.data.current
                const component = vueRouterThis.routerMap[url]
                return h(component)
            }
        })
    }

    // 添加hashchange监听事件，当地址栏上的hash地址发生时会触发改方法
    addUrlHashChangeListener() {
        window.addEventListener('hashchange', () => {
            const hashUrl = window.location.hash
            this.data.current = hashUrl
        })
    }
}